#pragma once
#include <catcake.h>
#include "wild_mot_data.h"
#include "SkinInfo.h"
#include "WildMdlData.h"
#include "wild_mdl.h"




class WildMot
{
	friend class ckJoin;
	friend class WildModel;
public:
	WildMot(void);
	~WildMot(void);
    

public:
    //! @cond
    ckDefineException(ExceptionInvalidArgument);
    ckDefineException(ExceptionInvalidCall);
    ckDefineException(ExceptionNotInitialized);
    //! @endcond

    /*!
        The motion play modes.
    */
    enum PlayMode
    {
        PLAY_NORMAL, //!< Play once.
        PLAY_LOOP, //!< Play repeatedly.
        PLAY_KEEP //!< Play and keep the last frame.
    };


    /*!
        Initializes this motion.
        @param[in] mdl A target model.
        @param[in] mot_data_id The ID of motion data.
    */
    void init(/*wildMdl* mdl,*/ ckID mot_data_id);

    /*!
        Returns the index of the current motion.
        @return The index of the current motion.
    */
    u16 getMotionIndex() const;

    /*!
        Returns the play mode.
        @return The play mode.
    */
    PlayMode getPlayMode() const;

    /*!
        Returns the play speed.
        @return The play speed.
    */
    r32 getPlaySpeed() const;

    /*!
        Returns the number of the frames for interporation.
        @return The number of the frames for interporation.
    */
    u16 getInterpFrame() const;

    /*!
        Returns whether playing motion.
        @return Whether playing motion.
    */
    bool isPlaying() const;

    /*!
        Plays the specified motion.
        @param[in] mdl A target model.
        @param[in] mot_index The index of a motion.
        @param[in] play_mode A play mode.
        @param[in] play_speed A play speed.
        @param[in] interp_frame The number of the frames for interporation.
    */
    void play(ckMat pose, u16 mot_index, PlayMode play_mode, r32 play_speed, u16 interp_frame);

    /*!
        Stops playing motion.
    */
    void stop();

    /*!
        Returns the frame number of next updating time.
    */
    r32 getNextUpdateFrame() const;

    /*!
        Updates this motion.
    */
    ckMat update( r32* nowPlayingFrame );

	ckMat updateByRootFrame( r32 nowPlayingFrame );

	void setMeshLocal( ckMat mat )
	{
		m_meshLocal = mat;
	}
private:
    struct InterpInfo
    {
        ckQuat quat;
        ckVec trans;
    };

    
    void operator=(const WildMot&);
	WildMot(const WildMot&);

    void uninit();

	//void changeModelByWeight(SkinInfo* skin, WildMdlData* model, const ckMat& parentMat);

    WildMotData m_mot_data;
    InterpInfo* m_interp_info;
    ckType<u8, PlayMode> m_play_mode;
    u16 m_mot_index;
    u16 m_interp_frame;
    r32 m_play_speed;
    r32 m_playing_frame;
    r32 m_interp_speed;
    r32 m_interp_ratio;

	//ckMat m_startPose;
	ckMat m_meshLocal;
	
};

void MatrixMultiply(ckMat& result, const ckMat& s1, const ckMat& s2);